package com.rich.widget.builder


import android.content.res.TypedArray
import android.graphics.Color
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.widget.TextView
import com.rich.widget.span.LinearGradientFontSpan
import com.rich.widget.span.MultiFontSpan
import com.rich.widget.span.SolidFontSpan
import com.rich.widget.span.StrokeFontSpan
import com.rich.widget.styleable.ITextColorStyleable

/**
 * 文字颜色构建者.
 */
class TextColorBuilder(
    private val mTextView: TextView,
    typedArray: TypedArray,
    styleable: ITextColorStyleable
) {

    var textColor: Int

    var textGradientColors: IntArray? = null
        private set

    var textGradientOrientation: Int
        private set

    var textStrokeColor = 0
        private set

    var textStrokeSize = 0
        private set

    /**
     * 是否包含实体文字颜色.
     */
    private var mHasTextSolidColor = false

    fun setTextColor(color: Int): TextColorBuilder {
        textColor = color
        clearTextGradientColors()
        return this
    }

    fun setTextGradientColors(startColor: Int, endColor: Int): TextColorBuilder {
        return setTextGradientColors(intArrayOf(startColor, endColor))
    }

    fun setTextGradientColors(startColor: Int, centerColor: Int, endColor: Int): TextColorBuilder {
        return setTextGradientColors(intArrayOf(startColor, centerColor, endColor))
    }

    fun setTextGradientColors(colors: IntArray): TextColorBuilder {
        textGradientColors = colors
        return this
    }

    /**
     * 是否为文字渐变效果.
     */
    fun isTextGradientColors(): Boolean =
        textGradientColors != null && textGradientColors?.isNotEmpty() == true

    /**
     * 清楚文字渐变色.
     */
    fun clearTextGradientColors() {
        textGradientColors = null
    }

    fun setTextGradientOrientation(orientation: Int): TextColorBuilder {
        textGradientOrientation = orientation
        return this
    }

    fun setTextStrokeColor(color: Int): TextColorBuilder {
        textStrokeColor = color
        return this
    }

    fun setTextStrokeSize(size: Int): TextColorBuilder {
        textStrokeSize = size
        return this
    }

    /**
     * 是否为文字描边效果.
     */
    fun hasTextStrokeColor(): Boolean = textStrokeColor != Color.TRANSPARENT && textStrokeSize > 0


    fun clearTextStrokeColor() {
        textStrokeColor = Color.TRANSPARENT
        textStrokeSize = 0
    }

    fun buildTextSpannable(text: CharSequence?): SpannableStringBuilder {

        val builder = SpannableStringBuilder(text)

        var linearGradientFontSpan: LinearGradientFontSpan? = null

        var strokeFontSpan: StrokeFontSpan? = null

        textGradientColors?.let {
            linearGradientFontSpan = LinearGradientFontSpan()
                .apply {
                    this.textGradientOrientation = this@TextColorBuilder.textGradientOrientation
                    this.textGradientColor = it
                }
        }

        if (hasTextStrokeColor()) {
            strokeFontSpan = StrokeFontSpan().apply {
                textStrokeColor = this@TextColorBuilder.textStrokeColor
                textStrokeSize = this@TextColorBuilder.textStrokeSize
            }
        }

        when {
            linearGradientFontSpan != null && strokeFontSpan != null -> {
                val multiFontSpan = MultiFontSpan(strokeFontSpan, linearGradientFontSpan!!)
                builder.setSpan(multiFontSpan, 0, builder.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
            }
            linearGradientFontSpan != null -> {
                builder.setSpan(
                    linearGradientFontSpan,
                    0,
                    builder.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }
            strokeFontSpan != null && mHasTextSolidColor -> {
                builder.setSpan(
                    MultiFontSpan(strokeFontSpan, SolidFontSpan(textColor)),
                    0,
                    builder.length,
                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                )
            }

            strokeFontSpan != null -> builder.setSpan(
                strokeFontSpan,
                0,
                builder.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        }

        return builder
    }

    fun intoTextColor() {
        if (isTextGradientColors() || hasTextStrokeColor()) {
            mTextView.text = buildTextSpannable(mTextView.text)
        }
    }

    init {
        typedArray.let {

            textColor =
                it.getColor(styleable.textColorStyleable, mTextView.textColors.defaultColor)
            mHasTextSolidColor = it.hasValue(styleable.textColorStyleable)

            if (it.hasValue(styleable.textStartColorStyleable) && it.hasValue(styleable.textEndColorStyleable)) {
                textGradientColors = if (it.hasValue(styleable.textCenterColorStyleable)) {
                    intArrayOf(
                        it.getColor(styleable.textStartColorStyleable, textColor),
                        it.getColor(styleable.textCenterColorStyleable, textColor),
                        it.getColor(styleable.textEndColorStyleable, textColor)
                    )
                } else {
                    intArrayOf(
                        it.getColor(styleable.textStartColorStyleable, textColor),
                        it.getColor(styleable.textEndColorStyleable, textColor)
                    )
                }
            }

            textGradientOrientation = it.getColor(
                styleable.textGradientOrientationStyleable,
                LinearGradientFontSpan.GRADIENT_ORIENTATION_HORIZONTAL
            )

            if (it.hasValue(styleable.textStrokeColorStyleable)) {
                textStrokeColor = it.getColor(styleable.textStrokeColorStyleable, 0)
            }

            if (it.hasValue(styleable.textStrokeSizeStyleable)) {

                textStrokeSize = it.getDimensionPixelSize(styleable.textStrokeSizeStyleable, 0)
            }
        }
    }
}